From c2e2e2993b106b44e7b86ca15e5ef1e3eead3aeb Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Wed, 25 Mar 2020 17:28:34 -0400 Subject: [PATCH] shortcutmanager: Use list models --- gtk/gtkshortcutmanager.c | 92 ++++++++++++++++++++++++++++----- gtk/gtkshortcutmanagerprivate.h | 12 +++++ gtk/gtkwidget.c | 12 +---- 3 files changed, 93 insertions(+), 23 deletions(-) create mode 100644 gtk/gtkshortcutmanagerprivate.h diff --git a/gtk/gtkshortcutmanager.c b/gtk/gtkshortcutmanager.c index 6853db9ce5..71a1b35eb1 100644 --- a/gtk/gtkshortcutmanager.c +++ b/gtk/gtkshortcutmanager.c @@ -20,6 +20,8 @@ #include "config.h" #include "gtkshortcutmanager.h" +#include "gtkshortcutmanagerprivate.h" +#include "gtkflattenlistmodel.h" /** * SECTION:gtkshortcutmanager @@ -29,36 +31,100 @@ * The GtkShortcutManager interface is used to implement * shortcut scopes. */ + G_DEFINE_INTERFACE (GtkShortcutManager, gtk_shortcut_manager, G_TYPE_OBJECT) -static void -complain_if_reached (gpointer should_be_gone) +void +gtk_shortcut_manager_create_controllers (GtkWidget *widget) +{ + GListStore *store; + GtkFlattenListModel *model; + GtkEventController *controller; + + store = g_list_store_new (GTK_TYPE_SHORTCUT_CONTROLLER); + model = gtk_flatten_list_model_new (GTK_TYPE_SHORTCUT, G_LIST_MODEL (store)); + g_object_unref (store); + g_object_set_data_full (G_OBJECT (widget), "gtk-shortcut-manager-bubble", model, g_object_unref); + controller = gtk_shortcut_controller_new_for_model (G_LIST_MODEL (model)); + gtk_event_controller_set_name (controller, "gtk-shortcut-manager-bubble"); + gtk_widget_add_controller (widget, controller); + + store = g_list_store_new (GTK_TYPE_SHORTCUT_CONTROLLER); + model = gtk_flatten_list_model_new (GTK_TYPE_SHORTCUT, G_LIST_MODEL (store)); + g_object_unref (store); + g_object_set_data_full (G_OBJECT (widget), "gtk-shortcut-manager-capture", model, g_object_unref); + controller = gtk_shortcut_controller_new_for_model (G_LIST_MODEL (model)); + gtk_event_controller_set_name (controller, "gtk-shortcut-manager-capture"); + gtk_event_controller_set_propagation_phase (controller, GTK_PHASE_CAPTURE); + gtk_widget_add_controller (widget, controller); +} + +static GtkFlattenListModel * +gtk_shortcut_manager_get_model (GtkShortcutManager *self, + GtkPropagationPhase phase) { - g_critical ("Shortcut controllers failed to clean up."); + switch (phase) + { + case GTK_PHASE_CAPTURE: + return g_object_get_data (G_OBJECT (self), "gtk-shortcut-manager-capture"); + case GTK_PHASE_BUBBLE: + return g_object_get_data (G_OBJECT (self), "gtk-shortcut-manager-bubble"); + case GTK_PHASE_NONE: + case GTK_PHASE_TARGET: + return NULL; + default: + g_assert_not_reached (); + return NULL; + } } static void gtk_shortcut_manager_default_add_controller (GtkShortcutManager *self, GtkShortcutController *controller) { - GSList *controllers; + GtkFlattenListModel *model; + GtkPropagationPhase phase; - controllers = g_object_steal_data (G_OBJECT (self), "gtk-shortcut-controllers"); - controllers = g_slist_prepend (controllers, g_object_ref (controller)); - g_object_set_data_full (G_OBJECT (self), "gtk-shortcut-controllers", controllers, complain_if_reached); + phase = gtk_event_controller_get_propagation_phase (GTK_EVENT_CONTROLLER (controller)); + model = gtk_shortcut_manager_get_model (self, phase); + if (model) + { + GListModel *store = gtk_flatten_list_model_get_model (model); + g_list_store_append (G_LIST_STORE (store), controller); + } } static void gtk_shortcut_manager_default_remove_controller (GtkShortcutManager *self, GtkShortcutController *controller) { - GSList *controllers; + GtkFlattenListModel *model; + GtkPropagationPhase phase; + + phase = gtk_event_controller_get_propagation_phase (GTK_EVENT_CONTROLLER (controller)); + model = gtk_shortcut_manager_get_model (self, phase); + if (model) + { + GListModel *store; + guint position; - controllers = g_object_steal_data (G_OBJECT (self), "gtk-shortcut-controllers"); - controllers = g_slist_remove (controllers, controller); - if (controllers) - g_object_set_data_full (G_OBJECT (self), "gtk-shortcut-controllers", controllers, complain_if_reached); - g_object_unref (controller); + store = gtk_flatten_list_model_get_model (model); +#if 0 && GLIB_CHECK_VERSION(2,64,0) + if (_g_list_store_find (G_LIST_STORE (store), controller, &position)) + g_list_store_remove (G_LIST_STORE (store), position); +#else + for (position = 0; position < g_list_model_get_n_items (G_LIST_MODEL (store)); position++) + { + GtkShortcutController *item = g_list_model_get_item (G_LIST_MODEL (store), position); + g_object_unref (item); + if (item == controller) + { + g_list_store_remove (G_LIST_STORE (store), position); + break; + } + } +#endif + } } static void diff --git a/gtk/gtkshortcutmanagerprivate.h b/gtk/gtkshortcutmanagerprivate.h new file mode 100644 index 0000000000..72424dba23 --- /dev/null +++ b/gtk/gtkshortcutmanagerprivate.h @@ -0,0 +1,12 @@ +#ifndef __GTK_SHORTCUT_MANAGER_PRIVATE_H__ +#define __GTK_SHORTCUT_MANAGER__PRIVATE_H__ + +#include "gtkshortcutmanager.h" + +G_BEGIN_DECLS + +void gtk_shortcut_manager_create_controllers (GtkWidget *widget); + +G_END_DECLS + +#endif /* __GTK_SHORTCUT_MANAGER_PRIVATE_H__ */ diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index 86a9b31e2c..0570a6c84c 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -60,6 +60,7 @@ #include "gtkshortcut.h" #include "gtkshortcutcontrollerprivate.h" #include "gtkshortcutmanager.h" +#include "gtkshortcutmanagerprivate.h" #include "gtkshortcuttrigger.h" #include "gtksizegroup-private.h" #include "gtksnapshotprivate.h" @@ -2444,16 +2445,7 @@ gtk_widget_init (GTypeInstance *instance, gpointer g_class) priv->root = (GtkRoot *) widget; if (g_type_is_a (G_TYPE_FROM_CLASS (g_class), GTK_TYPE_SHORTCUT_MANAGER)) - { - controller = gtk_shortcut_controller_new (); - gtk_shortcut_controller_set_run_managed (GTK_SHORTCUT_CONTROLLER (controller), TRUE); - gtk_widget_add_controller (widget, controller); - - controller = gtk_shortcut_controller_new (); - gtk_event_controller_set_propagation_phase (controller, GTK_PHASE_CAPTURE); - gtk_shortcut_controller_set_run_managed (GTK_SHORTCUT_CONTROLLER (controller), TRUE); - gtk_widget_add_controller (widget, controller); - } + gtk_shortcut_manager_create_controllers (widget); layout_manager_type = gtk_widget_class_get_layout_manager_type (g_class); if (layout_manager_type != G_TYPE_INVALID) -- 2.30.2